using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using twistmachinev2.Entity;
using twistmachinev2.OPCUA;
using twistmachinev2.CommonUse;

namespace twistmachinev2.OPCUA
{
    /// <summary>
    /// OPCUA服务管理器 - 单例模式，负责统一管理OPCUA连接、数据读取和订阅
    /// </summary>
    public class OpcUaServiceManager : IDisposable
    {
        private static OpcUaServiceManager _instance;
        private static readonly object _lock = new object();

        private OpcUaClient _opcUaClient;
        private OpcUaConfigService _configService;
        private DynamicOpcUaMapper _dynamicMapper;
        private Timer _readTimer;
        private bool _isInitialized = false;
        private bool _isConnected = false;
        private bool _disposed = false;

        // 数据变化事件，供各个WinForm页面订阅
        public event EventHandler<DataChangedEventArgs> DataChanged;
        public event EventHandler<ConnectionStatusChangedEventArgs> ConnectionStatusChanged;

        // 存储所有数据模型
        private Dictionary<string, DynamicDataModel> _dataModels;

        // 私有构造函数，确保单例
        private OpcUaServiceManager()
        {
            _dataModels = new Dictionary<string, DynamicDataModel>();
        }

        /// <summary>
        /// 获取单例实例
        /// </summary>
        public static OpcUaServiceManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock)
                    {
                        if (_instance == null)
                        {
                            _instance = new OpcUaServiceManager();
                        }
                    }
                }
                return _instance;
            }
        }

        /// <summary>
        /// 是否已连接
        /// </summary>
        public bool IsConnected => _isConnected;

        /// <summary>
        /// 是否已初始化
        /// </summary>
        public bool IsInitialized => _isInitialized;

        /// <summary>
        /// 配置服务
        /// </summary>
        public OpcUaConfigService ConfigService => _configService;

        /// <summary>
        /// 初始化OPCUA服务
        /// </summary>
        /// <param name="dbPath">数据库路径，为空则使用默认路径</param>
        /// <returns>初始化结果</returns>
        public async Task<OperateResult> InitializeAsync(string dbPath = null)
        {
            try
            {
                if (_isInitialized)
                {
                    return new OperateResult("OPCUA服务已经初始化");
                }

                // 初始化配置服务
                _configService = new OpcUaConfigService(dbPath);

                // 初始化OPCUA客户端
                _opcUaClient = new OpcUaClient();

                // 订阅连接状态变化事件
                _opcUaClient.ConnectionStatusChanged += OnConnectionStatusChanged;
                _opcUaClient.DataChanged += OnDataChanged;

                // 初始化动态映射器
                var configManager = new OpcUaConfigManager();
                _dynamicMapper = new DynamicOpcUaMapper(_opcUaClient, configManager);
                _dynamicMapper.Initialize();

                // 订阅动态映射器的数据变化事件
                _dynamicMapper.DataChanged += OnDataChanged;

                // 获取所有数据模型
                _dataModels = _dynamicMapper.GetAllDataModels();

                // 尝试连接到OPCUA服务器
                var connectResult = await ConnectAsync();

                // 如果连接成功，建立所有订阅
                if (connectResult.IsSuccess && _isConnected)
                {
                    // 先读取所有数据进行初始化
                    await _dynamicMapper.ReadAllNodesForInitAsync();
                    
                    // 然后建立订阅
                    _dynamicMapper.EstablishAllSubscriptions();
                }
                _isInitialized = true;
                // 启动定时读取数据（只读取非订阅节点）
                StartPeriodicDataReading(30000); // 30秒读取一次非订阅节点

                return new OperateResult();
            }
            catch (Exception ex)
            {
                return new OperateResult($"初始化OPCUA服务失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 连接到OPCUA服务器
        /// </summary>
        /// <returns>连接结果</returns>
        public async Task<OperateResult> ConnectAsync()
        {
            try
            {
                if (_opcUaClient == null)
                {
                    return new OperateResult("OPCUA客户端未初始化");
                }

                var serverUrl = _configService.GetServerUrl();
                var username = _configService.GetUsername();
                var password = _configService.GetPassword();

                var result = await _opcUaClient.ConnectAsync(serverUrl, username, password);

                if (result.IsSuccess)
                {
                    _isConnected = true;
                    // 连接成功后，订阅所有配置的节点
                    SubscribeAllNodes();
                }

                return result;
            }
            catch (Exception ex)
            {
                return new OperateResult($"连接OPCUA服务器失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        /// <returns>断开结果</returns>
        public Task<OperateResult> DisconnectAsync()
        {
            try
            {
                if (_opcUaClient != null)
                {
                    _opcUaClient.Disconnect();
                    _isConnected = false;
                }
                return Task.FromResult(new OperateResult());
            }
            catch (Exception ex)
            {
                return Task.FromResult(new OperateResult($"断开连接失败: {ex.Message}"));
            }
        }

        /// <summary>
        /// 获取数据模型
        /// </summary>
        /// <param name="objectName">对象名称，默认为"Default"</param>
        /// <returns>数据模型</returns>
        public DynamicDataModel GetDataModel(string objectName = "Default")
        {
            return _dataModels.TryGetValue(objectName, out var model) ? model : null;
        }

        /// <summary>
        /// 获取所有数据模型
        /// </summary>
        /// <returns>所有数据模型的字典</returns>
        public Dictionary<string, DynamicDataModel> GetAllDataModels()
        {
            return new Dictionary<string, DynamicDataModel>(_dataModels);
        }

        /// <summary>
        /// 读取单个节点数据
        /// </summary>
        /// <param name="nodeId">节点ID</param>
        /// <returns>读取结果</returns>
        public async Task<OperateResult<object>> ReadNodeAsync(string nodeId)
        {
            if (_dynamicMapper == null)
            {
                return new OperateResult<object>("动态映射器未初始化");
            }

            return await _dynamicMapper.ReadNodeAsync(nodeId);
        }

        /// <summary>
        /// 读取所有节点数据
        /// </summary>
        /// <returns>读取结果</returns>
        public async Task<OperateResult> ReadAllDataAsync()
        {
            if (_dynamicMapper == null)
            {
                return new OperateResult("动态映射器未初始化");
            }

            return await _dynamicMapper.ReadAllDataAsync();
        }

        /// <summary>
        /// 写入节点数据（带类型转换）
        /// </summary>
        /// <param name="nodeId">节点ID</param>
        /// <param name="value">要写入的值</param>
        /// <returns>写入结果</returns>
        public async Task<OperateResult> WriteNodeAsync(string nodeId, object value)
        {
            if (_dynamicMapper == null)
            {
                return new OperateResult("动态映射器未初始化");
            }

            return await _dynamicMapper.WriteNodeAsync(nodeId, value);
        }

        /// <summary>
        /// 批量写入节点数据（带类型转换）
        /// </summary>
        /// <param name="nodeIds">节点ID数组</param>
        /// <param name="values">要写入的值数组</param>
        /// <returns>写入结果</returns>
        public async Task<OperateResult> WriteNodesAsync(string[] nodeIds, object[] values)
        {
            if (_dynamicMapper == null)
            {
                return new OperateResult("动态映射器未初始化");
            }

            if (nodeIds.Length != values.Length)
            {
                return new OperateResult("节点ID数组和值数组长度不匹配");
            }

            // 逐个写入节点，确保每个节点都经过类型转换
            for (int i = 0; i < nodeIds.Length; i++)
            {
                var result = await _dynamicMapper.WriteNodeAsync(nodeIds[i], values[i]);
                if (!result.IsSuccess)
                {
                    return new OperateResult($"节点 {nodeIds[i]} 写入失败: {result.Message}");
                }
            }

            return new OperateResult();
        }

        /// <summary>
        /// 订阅所有配置的节点
        /// </summary>
        private OperateResult SubscribeAllNodes()
        {
            try
            {
                if (_dynamicMapper == null)
                {
                    return new OperateResult("动态映射器未初始化");
                }

                // 这里可以根据需要实现订阅逻辑
                // 目前先通过定时读取来模拟订阅

                return new OperateResult();
            }
            catch (Exception ex)
            {
                return new OperateResult($"订阅节点失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 启动定时数据读取
        /// </summary>
        /// <param name="intervalMs">读取间隔（毫秒）</param>
        private void StartPeriodicDataReading(int intervalMs)
        {
            _readTimer = new Timer(async _ => await PeriodicDataRead(), null, 0, intervalMs);
        }

        /// <summary>
        /// 定时数据读取方法
        /// </summary>
        private async Task PeriodicDataRead()
        {
            if (!_isConnected || _dynamicMapper == null)
                return;

            try
            {
                await _dynamicMapper.ReadAllDataAsync();
            }
            catch (Exception ex)
            {
                LogManager.LogError($"定时读取数据失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 连接状态变化事件处理
        /// </summary>
        private void OnConnectionStatusChanged(bool isConnected)
        {
            _isConnected = isConnected;
            ConnectionStatusChanged?.Invoke(this, new ConnectionStatusChangedEventArgs(isConnected));
        }

        /// <summary>
        /// 数据变化事件处理
        /// </summary>
        private void OnDataChanged(string nodeId, object value)
        {
            DataChanged?.Invoke(this, new DataChangedEventArgs(nodeId, value));
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (_disposed)
                return;

            _readTimer?.Dispose();
            _opcUaClient?.Dispose();
            _configService?.Dispose();
            _disposed = true;
        }
    }

    /// <summary>
    /// 数据变化事件参数
    /// </summary>
    public class DataChangedEventArgs : EventArgs
    {
        public string NodeId { get; }
        public object Value { get; }
        public DateTime Timestamp { get; }

        public DataChangedEventArgs(string nodeId, object value)
        {
            NodeId = nodeId;
            Value = value;
            Timestamp = DateTime.Now;
        }
    }

    /// <summary>
    /// 连接状态变化事件参数
    /// </summary>
    public class ConnectionStatusChangedEventArgs : EventArgs
    {
        public bool IsConnected { get; }
        public DateTime Timestamp { get; }

        public ConnectionStatusChangedEventArgs(bool isConnected)
        {
            IsConnected = isConnected;
            Timestamp = DateTime.Now;
        }
    }
}